package userscopelogic

import (
	"context"
	"strings"

	"go-zero-admin/apps/system/cmd/rpc/internal/svc"
	"go-zero-admin/apps/system/cmd/rpc/syspb"

	"github.com/duke-git/lancet/v2/convertor"
	"github.com/zeromicro/go-zero/core/logx"
)

type CheckUserRuleAuthLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
	getUserDataScopeLogic *GetUserDataScopeLogic
}

func NewCheckUserRuleAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CheckUserRuleAuthLogic {
	return &CheckUserRuleAuthLogic{
		ctx:                   ctx,
		svcCtx:                svcCtx,
		Logger:                logx.WithContext(ctx),
		getUserDataScopeLogic: NewGetUserDataScopeLogic(ctx, svcCtx),
	}
}

func (l *CheckUserRuleAuthLogic) CheckUserRuleAuth(in *syspb.CheckUserRuleAuthReq) (*syspb.CheckUserRuleAuthResp, error) {
	if in.GetUserId() == 0 || in.GetUrl() == "" {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: false}, nil
	}

	// 是否超管
	if l.getUserDataScopeLogic.IsAdminUser(in.GetUserId()) {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: true}, nil
	}

	// 根据链接名称获取菜单数据
	menu, err := l.svcCtx.SysMenuModel.FindOneByName(l.ctx, in.GetUrl())
	if err != nil {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: false}, nil
	}

	// 若存在不需要验证的条件则跳过
	if strings.EqualFold(menu.Condition, "nocheck") {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: true}, nil
	}

	// 判断权限操作
	enforcer := l.svcCtx.AdapterCasbin.SetCtxSession(l.ctx, nil).Enforcer
	if enforcer == nil {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: false}, nil
	}
	hasAccess, err := enforcer.Enforce(convertor.ToString(in.GetUserId()), convertor.ToString(menu.Id), "All")
	if err != nil || !hasAccess {
		return &syspb.CheckUserRuleAuthResp{IsHasAuth: false}, nil
	}

	return &syspb.CheckUserRuleAuthResp{IsHasAuth: true}, nil
}
